package com.wo56.pushmsgcenter.common.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.framework.core.SysContexts;
import com.wo56.pushmsgcenter.common.condition.OrderBy;
import com.wo56.pushmsgcenter.common.condition.SqlParam;
import com.wo56.pushmsgcenter.common.condition.Wrapper;
import com.wo56.pushmsgcenter.common.dao.interfaces.IDao;
import com.wo56.pushmsgcenter.common.utils.ReflectionKitUtil;

public class DaoImpl<P> implements IDao<P>{
	private static final Log logger = LogFactory.getLog(DaoImpl.class);
	@Override
	public List<P> getValueByWrapper(Wrapper wrapper) {
		Session session = SysContexts.getEntityManager(true);
		Criteria ca = session.createCriteria(poClass());
		List<SqlParam> paramList = wrapper.getSqlParams();
		if(paramList!=null&&paramList.size()>0){
			for(SqlParam sqlParam:paramList){
				String type = sqlParam.getType();
				switch (type) {
				case "=":
					ca.add(Restrictions.eq(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case "<>":
					ca.add(Restrictions.ne(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case "like":
					ca.add(Restrictions.like(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case ">":
					ca.add(Restrictions.gt(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case "<":
					ca.add(Restrictions.lt(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case "<=":
					ca.add(Restrictions.le(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case ">=":
					ca.add(Restrictions.ge(sqlParam.getColumn(), sqlParam.getValue()));
					break;
				case "in":
					ca.add(Restrictions.in(sqlParam.getColumn(), sqlParam.getValues()));
					break;
				default:
					break;
				}
			}
		}
		List<OrderBy> orderByList = wrapper.getOrderBys();
		if(orderByList!=null&&orderByList.size()>0){
			for(OrderBy orderBy:orderByList){
				String type = orderBy.getType();
				switch (type) {
				case "asc":
					ca.addOrder(Order.asc(orderBy.getColumn()));
					break;
				case "desc":
					ca.addOrder(Order.desc(orderBy.getColumn()));
					break;
				default:
					break;
				}
				
			}
		}

		return (List<P>)ca.list();
	}
	
	@Override
	public List<P> getAll() {
		Session session = SysContexts.getEntityManager(true);
		Criteria ca = session.createCriteria(poClass());
		return (List<P>)ca.list();
	}
	
	@Override
	public P get(Serializable id) {
		Session session = SysContexts.getEntityManager(true);
		return (P)session.get(poClass(), id);
	}

	@Override
	public P save(P p) {
		Session session = SysContexts.getEntityManager();
		session.save(p);
		return p;
	}

	@Override
	public P saveOrUpdate(P p) {
		Session session = SysContexts.getEntityManager();
		session.saveOrUpdate(p);
		return p;
	}

	@Override
	public P update(P p) {
		Session session = SysContexts.getEntityManager();
		session.update(p);
		return p;
	}

	@Override
	public boolean delete(P p) {
		Session session = SysContexts.getEntityManager();
        try {
        	session.delete(p);
        } catch (Exception e) {
            logger.warn("Warn: Unexpected exception.  Cause:" + e);
            return false;
        }
        return true;

	}

	@Override
	public boolean delete(Serializable id) {
		Session session = SysContexts.getEntityManager();
        try {
        	session.delete(id);
        } catch (Exception e) {
            logger.warn("Warn: Unexpected exception.  Cause:" + e);
            return false;
        }
        return true;
	}

	@Override
	public boolean insertBatch(List<P> list, int size) {
		Session session = SysContexts.getEntityManager();
        try {
            for (int i = 0; i < list.size(); i++) {
                session.save(list.get(i));
                if (i % size == 0) {
                    session.flush();
                    session.clear();
                }
            }
        } catch (Exception e) {
            logger.warn("Warn: Unexpected exception.  Cause:" + e);
            return false;
        }
        return true;

	}

	@Override
	public boolean updateBatch(List<P> list, int size) {
		Session session = SysContexts.getEntityManager();
        try {
            for (int i = 0; i < list.size(); i++) {
                session.update(list.get(i));
                if (i % size == 0) {
                    session.flush();
                    session.clear();
                }
            }
        } catch (Exception e) {
            logger.warn("Warn: Unexpected exception.  Cause:" + e);
            return false;
        }
        return true;
	}

	@Override
	public boolean saveOrUpdateBatch(List<P> list, int size) {
		Session session = SysContexts.getEntityManager();
        try {
            for (int i = 0; i < list.size(); i++) {
                session.saveOrUpdate(list.get(i));
                if (i % size == 0) {
                    session.flush();
                    session.clear();
                }
            }
        } catch (Exception e) {
            logger.warn("Warn: Unexpected exception.  Cause:" + e);
            return false;
        }
        return true;
	}
	
    protected Class<P> poClass() {
        return ReflectionKitUtil.getSuperClassGenricType(getClass(), 0);
    }


}
